{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Julia中的基本线性代数\n",
    "Author: Andreas Noack Jensen (MIT) (http://www.econ.ku.dk/phdstudent/noack/)\n",
    "(with edits from Jane Herriman)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先定义一个随机矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = rand(1:4,3,3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "定义一个元素全为1的向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = fill(1.0, (3,)) # = fill(1.0, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意$A$的类型为Array{Int64,2}，而$x$的类型为Array{Float64,1}。Julia定义向量Vector{Type}的别名为Array{Type,1}，矩阵Matrix{Type}的别名为Array{Type,2}。\n",
    "\n",
    "许多基础操作和其他语言一样\n",
    "#### 乘法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = A*x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 转置\n",
    "就像在其他语言中`A'`表示对`A`的共轭转置或者伴随矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "A'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们可以通过transpose获得转置矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "transpose(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 转置的乘法\n",
    "Julia中某些情况下可以省略`*`号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "A'A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 解线性方程组\n",
    "用方阵$A$表示的线性方程组$Ax=b$用左除运算符（函数）`\\`求解"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "A\\b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "超定线性方程组（overdetermined linear system）的情况下`A\\b`给出*最小二乘解（least squares solution）*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Atall = rand(3, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Atall\\b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "缺秩最小二乘问题（a rank-deficient least squares problem）情况下，会给出*极小范数最小二乘解（minimum norm least squares solution）* "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "v = rand(3)\n",
    "rankdef = hcat(v, v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rankdef\\b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "欠定问题（an underdetermined solution）下，会给出 最小范数解（minimum norm solution）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bshort = rand(2)\n",
    "Ashort = rand(2, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Ashort\\bshort"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LinearAlgebra包\n",
    "\n",
    "如上所示，Julia默认自带了很多线性代数操作，而标准库`LinearAlgebra`提供了更多的相关名词和函数。特别是它提供了因子分解和一些结构化矩阵类型。和其他包一样，可以通过`using LinearAlgebra`引入这些额外的特征。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 练习\n",
    "\n",
    "#### 10.1\n",
    "计算向量`v`和它自己的内积，并赋值给`dot_v`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "v = [1,2,3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "editable": false,
    "hide_input": true,
    "nbgrader": {
     "checksum": "b93dad361f66498eb2460d708f674220",
     "grade": true,
     "grade_id": "cell-913fef9b0d19cd52",
     "locked": true,
     "points": 1,
     "schema_version": 1,
     "solution": false
    }
   },
   "outputs": [],
   "source": [
    "@assert dot_v == 14"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 10.2\n",
    "计算向量v和它自己的外积，并赋值给`outer_v`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@assert outer_v == [1 2 3\n",
    "                    2 4 6\n",
    "                    3 6 9]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "editable": false,
    "hide_input": true,
    "nbgrader": {
     "checksum": "01642581e27c0ac19752cd90d11ac2ae",
     "grade": true,
     "grade_id": "cell-e6b6970ffe104df5",
     "locked": true,
     "points": 1,
     "schema_version": 1,
     "solution": false
    }
   },
   "outputs": [],
   "source": [
    "@assert cross_v == [0, 0, 0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "完成练习后请点击顶部的`Validate`按钮。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 1.0.5",
   "language": "julia",
   "name": "julia-1.0"
  },
  "language": "Julia",
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.0.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
